package com.huayi.datagovernance.utils;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.nio.charset.StandardCharsets;
import java.text.DecimalFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.zip.GZIPInputStream;
import java.util.zip.GZIPOutputStream;

/**
 * gzip压缩工具
 * @author wuch
 * @version 1.0
 * @date 2020/12/10 9:57
 */
public class GzipUtil {

    private static int count = 0 ; //总数量：一般在实际业务中是需要在数据库中获取到当前的数据总数量
    private static final String STR_FORMAT = "00000"; //需要格式化的流水号规则

    public static String uncompress(String str,String outEncoding) throws Exception {
        if (str == null || str.length() == 0) {
            return str;
        }
        try(ByteArrayOutputStream out = new ByteArrayOutputStream();
//            ByteArrayInputStream in = new ByteArrayInputStream(Base64.decodeBase64(str));
            ByteArrayInputStream in = new ByteArrayInputStream(Base64.decode(str));
            GZIPInputStream gunzip = new GZIPInputStream(in);)
        {
            byte[] buffer = new byte[512];
            int n;
            while ((n = gunzip.read(buffer)) >= 0) {
                out.write(buffer, 0, n);
            }
            return new String(out.toByteArray(), StandardCharsets.UTF_8);
        } catch (Exception e) {
            throw new Exception("解压数据失败",e);
        }
    }

    /**
     *  jd8 压缩，安卓必须8.0以上
     * @param str
     * @param inEncoding
     * @return
     */
    public static String compress(String str,String inEncoding) throws Exception {
        if (str == null || str.length() == 0) {
            return str;
        }
        try(ByteArrayOutputStream out = new ByteArrayOutputStream();
        )
        {
            GZIPOutputStream gzip = new GZIPOutputStream(out);
            gzip.write(str.getBytes(inEncoding));
            //获得输出流的数据之前，需要手动将gzip关闭，不能用try source的关闭机制
            gzip.close();
            System.out.println("数据压缩后大小(KB)"+ out.size()/1024);
//            return new String(java.util.Base64.getEncoder().encode(out.toByteArray()),StandardCharsets.UTF_8);
            return Base64.encode(out.toByteArray());
        } catch (Exception e) {
            throw new Exception("压缩数据失败",e);
        }
    }

    /**
     *  jd8 压缩，不进行base64编码
     * @param str
     * @param inEncoding
     * @return
     */
    public static String compressNoBase64(String str,String inEncoding) throws Exception {
        if (str == null || str.length() == 0) {
            return str;
        }
        try(ByteArrayOutputStream out = new ByteArrayOutputStream();
        )
        {
            GZIPOutputStream gzip = new GZIPOutputStream(out);
            gzip.write(str.getBytes(inEncoding));
            //获得输出流的数据之前，需要手动将gzip关闭，不能用try source的关闭机制
            gzip.close();
            System.out.println("数据压缩后大小(KB)"+ out.size()/1024);
//            return new String(java.util.Base64.getEncoder().encode(out.toByteArray()),StandardCharsets.UTF_8);
            return new String(out.toByteArray(), inEncoding);
        } catch (Exception e) {
            throw new Exception("压缩数据失败",e);
        }
    }
    /**
     *  jd8 解压
     * @param str
     * @param outEncoding
     * @return
     */
    public static String uncompressNoBase64(String str,String outEncoding) throws Exception {
        if (str == null || str.length() == 0) {
            return str;
        }
        try(ByteArrayOutputStream out = new ByteArrayOutputStream();
//            ByteArrayInputStream in = new ByteArrayInputStream(Base64.decodeBase64(str));
            ByteArrayInputStream in = new ByteArrayInputStream(str.getBytes());
            GZIPInputStream gunzip = new GZIPInputStream(in);)
        {
            byte[] buffer = new byte[512];
            int n;
            while ((n = gunzip.read(buffer)) >= 0) {
                out.write(buffer, 0, n);
            }
            return new String(out.toByteArray(), outEncoding);
        } catch (Exception e) {
            throw new Exception("解压数据失败",e);
        }
    }
    /**
     * 根据字节大小 （不处理中文）
     * @param str
     * @return
     */

    public static List<String> splitBySize(String str, int length) {
        char[] cs = str.toCharArray();
        StringBuilder result = new StringBuilder();
        List<String> resultList = new ArrayList<String>();
        int index = 0;
        for (char c: cs){
            index += String.valueOf(c).getBytes().length;
            if (index > length){
                resultList.add(result.toString());
                result.delete(0,index-1);
                result.append(c);
                index = 1;
            }else {
                result.append(c);
            }
        }
        if(result.length()>0){
            resultList.add(result.toString());
        }
        return resultList;
    }

    /**
     * 批次号生成
     *  获取年月日+三位流水号（根据当天生成的单据数量，生成流水号如：2019052200001,2019060100001）
     * @return
     */
    public static String getAutoBusiId() {
        // 所要获取的流水编码code
        StringBuffer code = new StringBuffer();
        // 设定所需的时间格式
        SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddd");
        // 获取当前时间并转化成所要的格式
        // 将格式化好的时间拼接到code上
        code.append(sdf.format(new Date()));
        // 根据格式化好的String类型的时间，查询数据库中当天所产生的单据数量生成流水号
        // 这里的count是需要在数据库中根据当天的日期,查询“单据”的创建时间符合条件的数量
        DecimalFormat dft = new DecimalFormat(STR_FORMAT);
        // 将获取到的数量按照所需的格式进行格式化
        String strNum = dft.format(count++);
        // 因为code的类型是StingBuffer，所以要将其转换成String类型
        return code.append(strNum).toString();
    }
}
